/***************************************************************************//**
* \file cy_sysrtc.h
* \version 1.0
*
* This file provides constants and parameter values for the APIs for the 
* Real-Time Clock (RTC).
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation.  All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*
*******************************************************************************/

/**
* \defgroup group_rtc Real-Time Clock (SysRtc)
* \{
*
* The Traveo II Real-time Clock (RTC) component provides an application interface 
* for keeping track of time and date. 
*
* \section group_rtc_section_configuration Configuration Considerations
* The component can be driven by WCO or ILO. The RTC component is driven by a
* clock that drives the BakClk. You need choose the source for BakClk as the 
* input clock source in the "Low Frequency Clocks" configuration window in the 
* CYDWR page. It should be noted that the accuracy of 
* the RTC depends on the accuracy of the input clock source.
*
* RTC interrupts handling
* The RTC hardware provides a single interrupt line to the NVIC for the 
* three RTC interrupts: Alarm 1, Alarm 2, and Century Interrupt. It is required 
* to check which exact interrupt (out of the three) was generated by checking 
* the Interrupt register.
* The RTC driver provides interrupt handler functions for every RTC interrupt:
* The Rtc_Alarm1Interrupt(), Rtc_Alarm2Interrupt(), and the 
* Rtc_CenturyInterrupt().
* All three functions are blank functions with the WEAK attribute. The 
* appropriate function(s) should be redefined in user source code in condition 
* that such event(s) is required.
* Rtc_Alarm1Interrupt(), Rtc_Alarm2Interrupt(), and the 
* Rtc_CenturyInterrupt() functions are called in the Rtc_Interrupt() function
*
* For RTC interrupt handling, the user should: <br>
* 1) Implement strong interrupt handling function(s) for the required events 
* (see above). <br>
* 2) Implement RTC interrupt handler and call Rtc_Interrupt() from there.<br>
* 3) Configure the RTC interrupt: <br>
* a) Set the mask for RTC required interrupt using 
* Cy_RTC_SetInterruptMask().<br>
* b) Initialize RTC interrupt by setting priority and the RTC interrupt 
* vector using Cy_SysInt_Init() function. <br>
* c) Enable RTC interrupt using the CMSIS core function NVIC_EnableIRQ().
*
* \section group_rtc_section_more_information More Information
* Use the RTC component when the system requires the current time or date. You 
* can also use the RTC when you do not need the current time and date but you 
* need accurate timing of events with one-second resolution.
*
* If the WCO is enabled, it should source the BakClk directly. Don't drive 
* the BakClk (RTC) by WCO which is routed to BakClk through LFCLK.
* This is because LFCLK is not available in all low power modes. 
*
*
* \section group_rtc_changelog Changelog
* <table class="doxtable">
*   <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
*   <tr>
*     <td>1.0</td>
*     <td>Initial version</td>
*     <td></td>
*   </tr>
*   <tr>
*     <td>1.1</td>
*     <td>Add calibration control function</td>
*     <td>Add atomic function for read bit and hour bit</td>
*     <td></td>
*   </tr>
* </table>
*
* \defgroup group_rtc_macro Macro
* \defgroup group_rtc_functions Functions
* \defgroup group_rtc_data_structures Data Structures
* \defgroup group_rtc_enums Enumerated types
*/

#if !defined (CY_SYSRTC_H_)
#define CY_SYSRTC_H_

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)
    #include "ip/cyip_srss_v2.h"
    #include "ip/cyip_backup_v2.h"
#elif defined (tviibh4m) || defined (tviibh8m)|| defined (tviibe4m) || defined (tviibh16m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviice4m)
    #include "ip/cyip_srss_v3.h"
    #include "ip/cyip_backup_v3.h"
#endif
#include "syslib/cy_syslib.h"
#include "sysreset/cy_sysreset.h"

#if defined(__cplusplus)
extern "C" {
#endif


/*******************************************************************************
*            Types definition
*******************************************************************************/

/**
* \addtogroup group_rtc_data_structures
* \{
*/

/**
* This is the data structure that is used to configure the Real time clock time 
* and date values.
*/
typedef struct stc_rtc_config
{
    /* Time information */
    uint32_t sec;                        /**< Seconds value, range [0-59] */
    uint32_t min;                        /**< Minutes value, range [0-59] */
    uint32_t hour;                       /**< Hour, range depends on hrMode, if hrMode = CY_RTC_24_HOURS, range [0-23];
                                              If hrMode = CY_RTC_12_HOURS, range [1-12] and appropriate AM/PM day period 
                                              should be set (amPm) */
    uint32_t amPm;                       /**< AM/PM hour period, range [0-1]. See \ref group_rtc_am_pm.
                                              This element is actual when hrMode = CY_RTC_12_HOURS. Firmware ignore this
                                              element if hrMode = CY_RTC_24_HOURS */
    uint32_t hrMode;                     /**< Hour mode, range [0-1], see \ref group_rtc_hour_format  */
    uint32_t dayOfWeek;                  /**< Day of the week, range [1-7], see \ref group_rtc_day_of_the_week */
    
    /* Date information  */
    uint32_t date;                        /**< Date of month, range [1-31] */
    uint32_t month;                       /**< Month,  range [1-12]. See \ref group_rtc_month */
    uint32_t year;                        /**< Year, range [0-99] */
} cy_stc_rtc_config_t;

/** Decimal data structure that is used to save the Alarms */
typedef struct stc_rtc_alarm
{
    /* Alarm time information  */
    uint32_t sec;                     /**< Alarm seconds, range [0-59]. 
                                        The appropriate ALARMX interrupt will be asserted on matching with this value
                                        if sec_en was previous enabled (sec_en = 1) */
    uint32_t sec_en;                  /**< Enable alarm on seconds matching, range [0-1] */
    uint32_t min;                     /**< Alarm minutes, range [0-59]. 
                                        The appropriate ALARMX interrupt will be asserted on matching with this value
                                        if min_en was previous enabled (min_en = 1) */
    uint32_t min_en;                  /**< Enable alarm on minutes matching, range [0-1] */
    uint32_t hour;                    /**< Alarm hours, range [0-23]
                                        The appropriate ALARMX interrupt will be asserted on matching with this value
                                        if hour_en was previous enabled (hour_en = 1) */
    uint32_t hour_en;                 /**< Enable alarm on hours matching, range  [0-1]  */
    uint32_t dayOfWeek;               /**< Alarm day of the week, range [1-7]
                                        The appropriate ALARMX interrupt will be asserted on matching with this value
                                        if dayOfWeek was previous enabled (dayOfWeek_en = 1) */
    uint32_t dayOfWeek_en;            /**< Enable alarm on day of the week matching, range [0-1] */

    /* Alarm date information */
    uint32_t date;                    /**< Alarm date, range [1-31]. 
                                        The appropriate ALARMX interrupt will be asserted on matching with this value
                                        if date_en was previous enabled (date_en = 1) */
    uint32_t date_en;                 /**< Enable alarm on date matching, range [0-1] */
    uint32_t month;                   /**< Alarm Month, range [1-12]. 
                                        The appropriate ALARMX interrupt will be asserted on matching with this value
                                        if date_en was previous enabled (date_en = 1) */
    uint32_t month_en;                /**< Enable alarm on month matching, range [0-1] */
    uint32_t alm_en;                  /**< Enable Alarm for appropriate ALARMX, range [0-1].
                                           If all alarm structure elements are disabled (alm_en = 1) the alarm interrupt
                                           will be asserted every second. */
} cy_stc_rtc_alarm_t;

/**
* This is DST structure for DST feature setting. Structure is combined with the
* fixed format and the relative format. It is used to save the DST time and date
* fixed or relative time format.
*/
typedef struct
{
    uint32_t format;        /**< DST format. Can be Relative(=0) or Fixed(=1), see /ref group_rtc_dst_format.
                                 Based on this value other structure elements should be filed or could be ignored */
    uint32_t hour;          /**< Should be filled for both format types.
                                 Hour is always presented in 24hour format, range[0-23] */
    uint32_t dayOfMonth;    /**< Day of Month, range[1-31]. This element should be filled if format = CY_RTC_DST_FIXED. 
                                 Firmware calculates this value in condition - format = CY_RTC_DST_RELATIVE is selected */
    uint32_t weekOfMonth;   /**< Week of month, range[1-6]. This element should be filled if format = CY_RTC_DST_RELATIVE.
                                 Firmware calculates dayOfMonth value based on weekOfMonth and dayOfWeek values */
    uint32_t dayOfWeek;     /**< Day of the week, this element should be filled in condition that 
                                 format = CY_RTC_DST_RELATIVE. Range[1- 7], see \ref group_rtc_day_of_the_week.
                                 Firmware calculates dayOfMonth value based on dayOfWeek and weekOfMonth values */
    uint32_t month;         /**< Month value, range[1-12], see \ref group_rtc_month.
                                 This value should be filled for both format types */
} cy_str_rtc_dst_format_t;

/** This is the DST structure to handle start DST and stop DST */
typedef struct
{
    cy_str_rtc_dst_format_t startDst;    /**< DST start time structure */
    cy_str_rtc_dst_format_t stopDst;     /**< DST stop time structure */
} cy_str_rtc_dst_t;

/** \} group_rtc_data_structures */


/*******************************************************************************
*    Enumerated Types and Parameters
*******************************************************************************/

/**
* \addtogroup group_rtc_enums
* \{
*/

/** This enumeration is used to set the clock source for the RTC block */
typedef enum
{
    CY_RTC_CLK_SRC_WCO              = 0u,       /**< WCO is the clock source */
    CY_RTC_CLK_SRC_ALTBAK           = 1u,       /**< ALTBAK is the clock source */
    CY_RTC_CLK_SRC_ILO_0            = 2u,       /**< ILO_0 is the clock source */
#if defined(SRSS_BACKUP_S40E_LPECO_PRESENT) && (SRSS_BACKUP_S40E_LPECO_PRESENT == 1)
    CY_RTC_CLK_SRC_LPECO_PRESCALER  = 3u,       /**< LPECO Prescaler output is the clock source */
#endif
} cy_en_rtc_clock_src_t;

/** This enumeration is used to set frequency by changing the it pre-scaler */
typedef enum
{
    CY_RTC_FREQ_WCO_32768_HZ = 0u, /**< prescaler value for 32.768 kHz oscillator */
    CY_RTC_FREQ_60_HZ,             /**< prescaler value for 60 Hz source */
    CY_RTC_FREQ_50_HZ,             /**< prescaler value for 50 Hz source */
} cy_en_rtc_clock_freq_t;

/** This enumeration is used to set/get information for alarm 1 or alarm 2 */
typedef enum cy_en_rtc_alarm
{
    CY_RTC_ALARM_1 = 0u,        /**< Alarm 1 enum */
    CY_RTC_ALARM_2              /**< Alarm 2 enum */
} cy_en_rtc_alarm_t;

typedef enum
{
    CY_EN_RTC_CALIB_SIGN_NEGATIVE = 0, /**< Negative sign: remove pulses  */
    CY_EN_RTC_CALIB_SIGN_POSITIVE = 1, /**< Positive sign: add pulses */
} cy_en_rtc_calib_sign_t;

typedef enum
{
    CY_EN_RTC_CAL_SEL_CAL512 = 0, /**< 512Hz wave, not affected by calibration setting, (not supported for 50/60Hz input clock: CTL.PRESCALER!=0) */
    CY_EN_RTC_CAL_SEL_CAL2   = 2, /**< 2Hz wave, includes the effect of the calibration setting, (not supported for 50/60Hz input clock: CTL.PRESCALER!=0) */
    CY_EN_RTC_CAL_SEL_CAL1   = 3, /**< 1Hz wave, includes the effect of the calibration setting (supported for all input clocks) */
} cy_en_rtc_cal_sel_t;

/** \} group_rtc_enums */

/**
* \addtogroup group_rtc_macro
* \{
*/

/** \cond INTERNAL */
/** Driver major version */
#define CY_RTC_DRV_VERSION_MAJOR                        (1ul)

/** Driver minor version */
#define CY_RTC_DRV_VERSION_MINOR                        (0ul)

/** Days per week definition */
#define CY_RTC_DAYS_PER_WEEK                            (7ul)

/** Month per year definition */
#define CY_RTC_MONTHS_PER_YEAR                          (12ul)

/** Maximum value of seconds and minutes */
#define CY_RTC_MAX_SEC_OR_MIN                           (59ul)

/** Biggest seconds or minutes definition */
#define CY_RTC_MAX_HOURS_24H                            (23ul)

/** Maximum value of year definition */
#define CY_RTC_MAX_YEAR                                 (99ul)

/** Number of RTC interrupts  */
#define CY_RTC_NUM_OF_INTR                              (3ul)

/** Number of RTC interrupts  */
#define CY_RTC_TRYES_TO_SETUP_DST                       (24ul)

/** RTC AM/PM bit for 12H hour mode */
#define CY_RTC_12HRS_PM_BIT                             (0x20ul)

/** Mask for reading RTC AM/PM bit for 12H mode  */
#define CY_RTC_BACKUP_RTC_TIME_RTC_PM                ((uint32_t) (CY_RTC_12HRS_PM_BIT << BACKUP_RTC_TIME_RTC_HOUR_Pos))

/** Definition of 6 WCO clocks in microseconds */
#define CY_RTC_DELAY_WHILE_READING_US                    (183ul)

/** Definition of 2 WCO clocks in microseconds */
#define CY_RTC_DELAY_WRITE_US                            (62ul)

/** Definition of 2 WCO clocks in microseconds */
#define CY_RTC_DELAY_FOR_NEXT_DST                        (2000ul)

/** Two thousand years definition  */
#define CY_RTC_TWO_THOUSAND_YEARS                        (2000ul)

/** Mask for reading RTC hour for 12H mode  */
#define CY_RTC_BACKUP_RTC_TIME_RTC_12HOUR                (0x1f0000ul)

/** Half day hours definition  */
#define CY_RTC_HOURS_PER_HALF_DAY                        (12ul)

/** First day of the month definition  */
#define CY_RTC_FIRST_DAY_OF_MONTH                        (1ul)

/** Internal definition for DST GetDSTStatus() function*/
#define CY_RTC_DST_MONTH_POSITION                        (10ul)

/** Internal definition for DST GetDSTStatus() function*/
#define CY_RTC_DST_DAY_OF_MONTH_POSITION                 (5ul)

/** RTC days in months table */
extern uint8_t const cy_Rtc_daysInMonthTbl[CY_RTC_MONTHS_PER_YEAR];

/** \endcond */

//RMKN #ifndef  en_result_t
    /** Will be removed in final code*/
    //#define en_result_t  status
//#endif

/**
 *****************************************************************************
 ** \brief error codes.
 **
 *****************************************************************************/
typedef enum en_result
{
    CY_RTC_SUCCESS              = 0,    /*! No error */
    CY_RTC_BAD_PARAM            = 1,    /*!< Provided parameter is not valid */
    CY_RTC_INVALID_STATE        = 2,    /*!< A requested operation could not be completed */
    CY_RTC_TIMEOUT              = 3     /*! Timeout */
} cy_en_rtc_status_t;

/**
* \defgroup group_rtc_day_of_the_week Day of the week definitions
* \{
* Definitions of days in the week
*/
#define CY_RTC_SUNDAY                                   (1ul) /**< Sequential number of Sunday in the week */
#define CY_RTC_MONDAY                                   (2ul) /**< Sequential number of Monday in the week */
#define CY_RTC_TUESDAY                                  (3ul) /**< Sequential number of Tuesday in the week */
#define CY_RTC_WEDNESDAY                                (4ul) /**< Sequential number of Wednesday in the week */
#define CY_RTC_THURSDAY                                 (5ul) /**< Sequential number of Thursday in the week */
#define CY_RTC_FRIDAY                                   (6ul) /**< Sequential number of Friday in the week */
#define CY_RTC_SATURDAY                                 (7ul) /**< Sequential number of Saturday in the week */
/** \} group_rtc_day_of_the_week */

/**
* \defgroup group_rtc_dst_week_of_month Week of month definitions
* \{
* Week of Month setting constants definitions for Daylight Saving Time feature
*/
#define CY_RTC_FIRST_WEEK_OF_MONTH                      (1ul)  /**< First week in the month */
#define CY_RTC_SECOND_WEEK_OF_MONTH                     (2ul)  /**< Second week in the month  */
#define CY_RTC_THIRD_WEEK_OF_MONTH                      (3ul)  /**< Third week in the month  */
#define CY_RTC_FOURTH_WEEK_OF_MONTH                     (4ul)  /**< Fourth week in the month  */
#define CY_RTC_FIFTH_WEEK_OF_MONTH                      (5ul)  /**< Fifth week in the month  */
#define CY_RTC_LAST_WEEK_OF_MONTH                       (6ul)  /**< Last week in the month  */
/** \} group_rtc_dst_week_of_month */

/**
* \defgroup group_rtc_month Month definitions
* \{
* Constants definition for Months
*/
#define CY_RTC_JANUARY                                  (1ul)   /**< Sequential number of January in the year */
#define CY_RTC_FEBRUARY                                 (2ul)   /**< Sequential number of February in the year */
#define CY_RTC_MARCH                                    (3ul)   /**< Sequential number of March in the year */
#define CY_RTC_APRIL                                    (4ul)   /**< Sequential number of April in the year */
#define CY_RTC_MAY                                      (5ul)   /**< Sequential number of May in the year */
#define CY_RTC_JUNE                                     (6ul)   /**< Sequential number of June in the year */
#define CY_RTC_JULY                                     (7ul)   /**< Sequential number of July in the year */
#define CY_RTC_AUGUST                                   (8ul)   /**< Sequential number of August in the year */
#define CY_RTC_SEPTEMBER                                (9ul)   /**< Sequential number of September in the year */
#define CY_RTC_OCTOBER                                  (10ul)  /**< Sequential number of October in the year */
#define CY_RTC_NOVEMBER                                 (11ul)  /**< Sequential number of November in the year */
#define CY_RTC_DECEMBER                                 (12ul)  /**< Sequential number of December in the year */
/** \} group_rtc_month */

/**
* \defgroup group_rtc_days_in_month Number of days in month definitions
* \{
* Definition of days in current month
*/
#define CY_RTC_DAYS_IN_JANUARY                          (31u)  /**< Number of days in January */
#define CY_RTC_DAYS_IN_FEBRUARY                         (28u)  /**< Number of days in February */
#define CY_RTC_DAYS_IN_MARCH                            (31u)  /**< Number of days in March */
#define CY_RTC_DAYS_IN_APRIL                            (30u)  /**< Number of days in April */
#define CY_RTC_DAYS_IN_MAY                              (31u)  /**< Number of days in May */
#define CY_RTC_DAYS_IN_JUNE                             (30u)  /**< Number of days in June */
#define CY_RTC_DAYS_IN_JULY                             (31u)  /**< Number of days in July */
#define CY_RTC_DAYS_IN_AUGUST                           (31u)  /**< Number of days in August */
#define CY_RTC_DAYS_IN_SEPTEMBER                        (30u)  /**< Number of days in September */
#define CY_RTC_DAYS_IN_OCTOBER                          (31u)  /**< Number of days in October */
#define CY_RTC_DAYS_IN_NOVEMBER                         (30u)  /**< Number of days in November */
#define CY_RTC_DAYS_IN_DECEMBER                         (31u)  /**< Number of days in December */
/** \} group_rtc_days_in_month */

/**
* \defgroup group_rtc_am_pm AM/PM status definitions
* \{
* Definitions for 12 hour format for indicating the AM/PM period of day
*/
#define CY_RTC_AM                                       (0ul) /**< AM period of day */
#define CY_RTC_PM                                       (1ul) /**< PM period of day */
/** \} group_rtc_am_pm */

/**
* \defgroup group_rtc_hour_format Hour format definitions
* \{
* Definitions for hour format
*/
#define CY_RTC_24_HOURS                                 (0ul) /**< The 24 hour format */
#define CY_RTC_12_HOURS                                 (1ul) /**< The 12 hour (AM/PM) format */
/** \} group_rtc_hour_format */

/**
* \defgroup group_rtc_busy_status RTC Status definitions
* \{
* Definitions for indicating the RTC BUSY bit 
*/
#define CY_RTC_BUSY                                     (1ul) /**< RTC Busy bit is set, RTC is pending */
#define CY_RTC_AVAILABLE                                (0ul) /**< RTC Busy bit is cleared, RTC is available */
/** \} group_rtc_busy_status */

/**
* \defgroup group_rtc_write_status RTC Register Write status definitions
* \{
* Definitions for configuring the RTC Write
*/
#define CY_RTC_WRITE_DISABLED                           (0ul) /**< Writing the RTC is disabled */ 
#define CY_RTC_WRITE_ENABLED                            (1ul) /**< Writing the RTC is enabled */ 
/** \} group_rtc_write_status */

/**
* \defgroup group_rtc_alarm_enable Alarm configuration definitions
* \{
* Definitions for Alarm functionality
*/
#define CY_RTC_ALARM_DISABLE                            (0ul) /**< Disable alarm */ 
#define CY_RTC_ALARM_ENABLE                             (1ul) /**< Enable alarm */ 
/** \} group_rtc_alarm_enable */

/**
* \defgroup group_rtc_macro_interrupts RTC Interrupt sources
* \{
* Definitions for RTC interrupt sources
*/
/** Alarm 1 status */
#define CY_RTC_INTR_ALARM1                               BACKUP_INTR_ALARM1_Msk

/** Alarm 2 status */
#define CY_RTC_INTR_ALARM2                               BACKUP_INTR_ALARM2_Msk

/**
* This interrupt will occur when the year is reached to 2100 which is rolling
* over the year field value from 99 to 0
*/
#define CY_RTC_INTR_CENTURY                              BACKUP_INTR_CENTURY_Msk
/** \} group_rtc_macro_interrupts */


/**
* \addtogroup group_rtc_dst_format DST time format definitions
* \{
* Daylight saving Time format definitions
*/
#define CY_RTC_DST_RELATIVE                              (0ul) /**< Relative DST format */
#define CY_RTC_DST_FIXED                                 (1ul) /**< Fixed DST format */
/** \} group_rtc_dst_format */

/** \} group_rtc_macro */


/*******************************************************************************
*    Function Prototypes
*******************************************************************************/

/**
* \addtogroup group_rtc_functions
* \{
*/

/*******************************************************************************
* Function Name: Cy_RTC_IsExternalResetOccurred
****************************************************************************//**
*
* The function checks the reset cause and returns the Boolean result.
*
* \return
* True if the reset reason is the power cycle and the XRES (external reset) <br>
* False if the reset reason is other than power cycle and the XRES.
*
* \note Based on a return value the RTC time and date can be updated or skipped 
* after the device reset. For example, you should skip the 
* Cy_RTC_SetAlarmDateAndTime() call function if internal WDT reset occurs.
*
*******************************************************************************/
bool Cy_RTC_IsExternalResetOccurred(void);

/*******************************************************************************
* Function Name: Rtc_ConvertDayOfWeek
****************************************************************************//**
*
* \brief  Returns a day of the week for a year, month, and day of month that are passed
*         through parameters. Zeller's congruence is used to calculate the day of
*         the week. 
*         RTC HW block does not provide the converting function for day of week. This 
*         function should be called before Cy_RTC_SetDateAndTime() to get the day of 
*         week.
*
*         For the Georgian calendar, Zeller's congruence is:
*         h = (q + [13 * (m + 1)] + K + [K/4] + [J/4] - 2J) mod 7
*
*         h - The day of the week (0 = Saturday, 1 = Sunday, 2 = Monday, ., 6 = Friday).
*         q - The day of the month.
*         m - The month (3 = March, 4 = April, 5 = May, ..., 14 = February)
*         K - The year of the century (year mod 100).
*         J - The zero-based century (actually [year/100]) For example, the zero-based
*         centuries for 1995 and 2000 are 19 and 20 respectively (not to be
*         confused with the common ordinal century enumeration which indicates
*         20th for both cases).

*
* \param  day   : The day of the month (1..31).
*         month : The month of the year, (1..12) see \ref group_rtc_month.
*         year  : The year value. Valid range - 2000...2100.
*
* \return Returns a day of the week, see \ref group_rtc_day_of_the_week.
*
* \note   In this algorithm January and February are counted as months 13 and 14
*         of the previous year.
*
*******************************************************************************/
uint32_t Cy_Rtc_ConvertDayOfWeek(uint32_t day, uint32_t month, uint32_t year);

/*******************************************************************************
* Function Name: Rtc_IsLeapYear
****************************************************************************//**
*
* \breif  Checks whether the year passed through the parameter is leap or not.
*
*         This API is for checking an invalid value input for leap year.
*         RTC HW block does not provide a validation checker against time/date values, 
*         the valid range of days in Month should be checked before SetDateAndTime()
*         function call. Leap year is identified as a year that is a multiple of 4 
*         or 400 but not 100.
*
* \param  year : The year to be checked.
*
* \return false : The year is not leap;
*         true  : The year is leap.
*
*******************************************************************************/
bool Cy_Rtc_IsLeapYear(uint32_t year);

/*******************************************************************************
* Function Name: Rtc_DaysInMonth
****************************************************************************//**
*
* \brief  Returns a number of days in a month passed through the parameters. This API
*         is for checking an invalid value input for days.
*         RTC HW block does not provide a validation checker against time/date values, 
*         the valid range of days in Month should be checked before SetDateAndTime()
*         function call.
*
* \param  month : The month of the year, see \ref group_rtc_month.
*         year  : A year value.
*
* \return A number of days in a month in the year passed through the parameters.
*
*******************************************************************************/
uint32_t Cy_Rtc_DaysInMonth(uint32_t month, uint32_t year);

/*******************************************************************************
* Function Name: Rtc_SyncRegisters
****************************************************************************//**
*
* The Synchronizer updates RTC values into AHB RTC user registers from the 
* actual RTC. By calling this function, the actual RTC register values will be 
* copied to AHB user registers.
*
* \note Only after calling Rtc_SyncRegisters() the RTC time values can be 
* read.
* After Rtc_SyncRegisters() calling the snapshot of the actual RTC registers
* are copied to the user registers. Meanwhile the RTC is continuing to clock.
*
*******************************************************************************/
void Cy_Rtc_SyncRegisters(void);

/*******************************************************************************
* Function Name: Rtc_WriteEnable
****************************************************************************//**
*
* Set/Clear writeable option for RTC user registers. When the Write bit is set, 
* data can be written into the RTC user registers. After all the RTC writes are 
* done, the firmware must clear (call Rtc_WriteEnable(RTC_WRITE_DISABLED))
* the Write bit for the RTC update to take effect. 
*
* Set/Clear cannot be done if the RTC is still busy with a previous update 
* (RTC_BUSY = 1) or RTC Reading is executing.
*
* \param
* writeEnable see \ref group_rtc_write_status.
*
* \return
* en_result_t RET_SUCCESS - Set/Clear Write bit was successful;
* RET_CANCELED - RTC is busy with a previous update.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_WriteEnable(uint32_t writeEnable);

/*******************************************************************************
* Function Name: Rtc_GetSyncStatus
****************************************************************************//**
*
* Return current status of CY_RTC_BUSY. The status indicates  
* synchronization between RTC user register and the actual RTC register. 
* CY_RTC_BUSY bit will be set if it is synchronizing. It is not possible to set 
* the Read or Write bit until CY_RTC_BUSY clears.
*
* \return
* The status of RTC user register synchronization, see
* \ref group_rtc_busy_status
*
*******************************************************************************/
uint32_t Cy_Rtc_GetSyncStatus(void);

/*******************************************************************************
* Function Name: Rtc_GetHoursFormat
****************************************************************************//**
*
* \brief  Returns current 12/24 hours mode.
*
* \param  None
*
* \return The current RTC hour format, see \ref group_rtc_hour_format.
*
* \note   Before getting the RTC current hour mode the Rtc_SyncRegisters() function
*         should be called.
*
*******************************************************************************/
uint32_t Cy_Rtc_GetHoursFormat(void);

/*******************************************************************************
* Function Name: Cy_Rtc_clock_source
****************************************************************************//**
* Sets the clock source for the RTC block.
*
* \param
* clock_source The clock source to be set, see \ref cy_en_rtc_clock_src_t.
*
* \return
* none
*
*******************************************************************************/
void Cy_Rtc_clock_source(cy_en_rtc_clock_src_t clock_source);

/*******************************************************************************
* Function Name: Rtc_Init
****************************************************************************//**
* \brief  Initializes the RTC driver and returns an RTC register address.
*
* \param  *config : The pointer to the RTC configuration structure, see \ref 
*                   stc_rtc_config_t.
*
* \return en_result_t : *config checking result. If the pointer is NULL, 
*         returns an error.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_Init(cy_stc_rtc_config_t const *config);

/*******************************************************************************
* Function Name: Cy_Rtc_SetHourBit
****************************************************************************//**
*
* Only set the hour bit with out any checking. Please make sure write bit has 
* been enabled before calling this function.
*
* \param hour Hour value to be set. only 0~23 will be accepted.
*
* \return \ref cy_en_rtc_status_t
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetHourBit(uint8_t hour);

/*******************************************************************************
* Function Name: Cy_Rtc_SetReadBit
****************************************************************************//**
*
* Sets READ bit with checking busy status.
*
* \return \ref cy_en_rtc_status_t 
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetReadBit(void);

/*******************************************************************************
* Function Name: Cy_Rtc_ClearReadBit
****************************************************************************//**
*
* Clears READ bit.
*
* \return \ref cy_en_rtc_status_t
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_ClearReadBit(void);

/*******************************************************************************
* Function Name: Cy_Rtc_IsReadBitSet
****************************************************************************//**
*
* Returns READ bit status.
*
* \return true : If the READ bit is set.
*         false: If the READ bit is cleared.
*
*******************************************************************************/
bool Cy_Rtc_IsReadBitSet(void);

/*******************************************************************************
* Function Name: Cy_Rtc_CalibrationControlEnable
****************************************************************************//**
*
* Set calibration control register with checking write bit status.
*
* \param calib_val
*
* \param calib_sign \ref cy_en_rtc_calib_sign_t
*
* \param calib_val \ref cy_en_rtc_cal_sel_t
*
* \return \ref cy_en_rtc_status_t
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_CalibrationControlEnable(uint8_t calib_val, cy_en_rtc_calib_sign_t calib_sign, cy_en_rtc_cal_sel_t cal_sel);

/*******************************************************************************
* Function Name: Cy_Rtc_CalibrationControlDisable
****************************************************************************//**
*
* Disable calibration control.
*
* \return \ref cy_en_rtc_status_t
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_CalibrationControlDisable(void);

/*******************************************************************************
* Function Name: Rtc_SetDateAndTime
****************************************************************************//**
*
* \brief  Sets the time and date values into the RTC_TIME and RTC_DATE registers.
*
* \param  dateTime  : The pointer to the RTC configuration structure, see
*                  \ref stc_rtc_config_t.
*
* \return en_result_t : A validation check result of date and month.  
*                       Returns an error, if the date range is invalid.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetDateAndTime(cy_stc_rtc_config_t const *dateTime);

/*******************************************************************************
* Function Name: Rtc_GetDateAndTime
****************************************************************************//**
*
* \brief  Gets the current RTC time and date. The AHB RTC Time and Date register values 
*         are stored into the *dateTime structure.
*
* \param  dateTime : The RTC time and date structure, see \ref group_rtc_data_structures.
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_GetDateAndTime(cy_stc_rtc_config_t *dateTime);

/*******************************************************************************
* Function Name: Rtc_SetAlarmDateAndTime
****************************************************************************//**
*
* \brief  Sets alarm time and date values into the ALMx_TIME and ALMx_DATE registers.
*
* \param  alarmDateTime : The alarm configuration structure, see \ref stc_rtc_alarm_t.
*         alarmIndex    : The alarm index to be configured, see \ref en_rtc_alarm_t.
*
* \return en_result_t : A validation check result of date and month. Returns an error, if
*                       the date range is invalid.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetAlarmDateAndTime(cy_stc_rtc_alarm_t const *alarmDateTime, cy_en_rtc_alarm_t alarmIndex );

/*******************************************************************************
* Function Name: Rtc_GetAlarmDateAndTime
****************************************************************************//**
*
* \brief  Returns the current alarm time and date values from the ALMx_TIME and 
*         ALMx_DATE registers.
*
* \param  alarmDateTime : The alarm configuration structure, see \ref stc_rtc_alarm_t.
*        alarmIndex    : The alarm index to be configured, see \ref en_rtc_alarm_t.
*
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_GetAlarmDateAndTime(cy_stc_rtc_alarm_t *alarmDateTime, cy_en_rtc_alarm_t alarmIndex);

/*******************************************************************************
* Function Name: Rtc_SetDateAndTimeDirect
****************************************************************************//**
*
* \brief  Sets the time and date values into the RTC_TIME and RTC_DATE registers using 
*         direct time parameters.
*
* \param  sec   : The second valid range is [0-59].
*         min   : The minute valid range is [0-59].
*         hour  : The hour valid range is [0-23]. This parameter type should be presented 
*               in the 24-hour type. The function reads the current 12/24-hour mode, 
*               then converts the hour value properly as the mode.
*         date  : The date valid range is [1-31], if the month of February is 
*               selected as the Month parameter, then the valid range is [0-29].
*        month : The month valid range is [1-12].
*        year  : The year valid range is [0-99].
*
* \return en_result_t : A validation check result of date and month. Returns an error, if 
*                       the date range is invalid or the RTC time and date set was cancelled: the RTC 
*                       Write bit was not set, the RTC was synchronizing.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetDateAndTimeDirect(uint32_t sec, uint32_t min, uint32_t hour, 
                                     uint32_t date, uint32_t month, uint32_t year);

/*******************************************************************************
* Function Name: Rtc_SetAlarmDateAndTimeDirect
****************************************************************************//**
*
* \brief  Sets alarm time and date values into the ALMx_TIME and ALMx_DATE 
*         registers using direct time parameters. ALM_DAY_EN is default 0 (=ignore) for 
*         this function.
*
* \param  sec   : The second valid range is [0-59].
*         min   : The minute valid range is [0-59].
*         hour  : The hour valid range is [0-23]. This parameter type should be presented 
*                 in the 24-hour type. The function reads the current 12/24-hour mode, 
*                 then converts the hour value properly as the mode.
*         date  : The date valid range is [1-31], if the month of February is 
*                 selected as the Month parameter, then the valid range is [0-29].
*         month : The month valid range is [1-12].
*    alarmIndex : The alarm index to be configured, see \ref en_rtc_alarm_t.
*
* \return en_result_t : A validation check result of date and month. Returns an error, if 
*                       the date range is invalid.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetAlarmDateAndTimeDirect(uint32_t sec, uint32_t min, uint32_t hour, 
                                          uint32_t date, uint32_t month, uint32_t alarmIndex);

/*******************************************************************************
* Function Name: Rtc_SetHoursFormat
****************************************************************************//**
*
* \brief  Sets the 12/24-hour mode.
*
* \param  hourMode : The current hour format, see \ref group_rtc_hour_format.
*
* \return en_result_t : A validation check result of RTC register update.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetHoursFormat(uint32_t hourMode);

/*******************************************************************************
* Function Name: RTC_SelectFrequencyPrescaler()
****************************************************************************//**
*
* \brif  Selects the RTC pre-scaler value and changes its clock frequency. Under 
*        condition that the external 32.768 kHz WCO is absent on the board, the RTC can
*        be driven by an external 50-Hz or 60-Hz sine-wave clock source, for example 
*        the wall AC frequency.
*
* \param clkSel : clock frequency, see \ref en_rtc_clock_freq_t.
*
* In addition to generating the 32.768 kHz clock from external crystals, the WCO
* can be sourced by an external clock source (50 Hz or 60Hz), even the wall AC 
* frequency as a timebase, to drive the RTC using wco_out and wco_in pins. 
* The API helps select between the RTC sources:
* * The external crystal WCO <br>
* * An external 50-Hz or 60-Hz sine-wave clock source
*
* If you want to use an external 50-Hz or 60-Hz sine-wave clock source to 
* drive the WCO, the next procedure is required: <br>
* 1) Disable the WCO <br>
* 2) Drive the wco_out and wco_in pins to an external signal source* <br>
* 3) Call Rtc_SelectFrequencyPrescaler(RtcFreq60Hz) if you want to 
* drive the WCO, for example, with 60 Hz source <br>
* 4) Enable the WCO <br>
*
* If you want to use the WCO after using an external 50-Hz or 60-Hz sine-wave 
* clock source:  <br>
* 1) Disable the WCO <br>
* 2) Drive off wco_out and wco_in pins with external signal source <br>
* 3) Call Rtc_SelectFrequencyPrescaler(RtcFreqWco32768Hz) <br>
* 4) Enable the WCO <br>
* 
* \warning 
* There is a limitation to the external clock source frequencies. Only two 
* frequencies are allowed - 50 Hz or 60 Hz. Note that this limitation is related
* to the RTC pre-scaling feature presented in this function. This 
* limitation is not related to WCO external clock sources which can drive the 
* WCO in the bypass mode. 
*
* \note 
* 50-Hz and 60-Hz external pin sources must be a sine wave, connected to the 
* wco_input pin with the wco_out pin floating.
* An external 60-Hz sine wave derived from the 60Hz/120V mains through a 100:1 
* capacitive divider. For the capacitive divider, connect a 220pF/6V capacitor 
* between wco_input and ground, a 2,2pF/200V cap between wco_input pad and 
* the 60Hz/120V mains input.
* The same setup should be used for the European 50Hz/220V mains standard, 
* except that a 1pF/250V cap should be used between wco_input pad and the mains 
* input, in the capacitive divider.
*
* \note 
* The 32.768 kHz WCO input must be a square wave, connected to the wco_out pin,
* with the wco_input pin grounded. 
*
*******************************************************************************/
void Cy_Rtc_SelectFrequencyPrescaler(cy_en_rtc_clock_freq_t clkSel);

/*******************************************************************************
* Function Name: Rtc_EnableDstTime
****************************************************************************//**
* 
* \brief  The function sets the DST time and configures the ALARM2 interrupt register 
*         with the appropriate DST time. This function sets the DST stop time if the 
*         current time is already in the DST period. The DST period is a period of time 
*         between the DST start time and DST stop time. The DST start time and DST stop 
*         time is presented in the DST configuration structure, see \ref str_rtc_dst_t.
*
* \param  DstTime : The DST configuration structure, see \ref str_rtc_dst_t.
*
* \return en_result_t : A validation check result of RTC register update.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_EnableDstTime(cy_str_rtc_dst_t const *DstTime);

/*******************************************************************************
* Function Name: Rtc_SetNextDstTime
****************************************************************************//**
*
* \brief  Set the next time of the DST. This function sets the time to ALARM2 for a next
*         DST event. If Rtc_GetDSTStatus() is true(=1), the next DST event should be
*         the DST stop, then this function should be called with the DST stop time. 
*
* If the time format(.format) is relative option(=0), the Rtc_RelativeToFixed()
* is called to convert to a fixed date. 
*
* \param  nextDst : The structure with time at which a next DST event should occur 
*                   (ALARM2 interrupt should occur). See \ref stc_rtc_config_t.
*
* \return en_result_t : A validation check result of RTC register update.
*
*******************************************************************************/
cy_en_rtc_status_t Cy_Rtc_SetNextDstTime(cy_str_rtc_dst_format_t const *nextDst);

/*******************************************************************************
* Function Name: Rtc_GetDstStatus
****************************************************************************//**
*
* \brief  Returns the current DST status using given time information. This function 
*         is used in the initial state of a system. If the DST is enabled, the system 
*         will set the DST start or stop as a result of this function.
*
* \param  DstTime : The DST configuration structure, see \ref str_rtc_dst_t.
*
* \return false : The current date and time is out of the DST period.
*         true  : The current date and time is in the DST period.
*
*******************************************************************************/
bool Cy_Rtc_GetDstStatus(cy_str_rtc_dst_t const *DstTime);

/*******************************************************************************
* Function Name: Rtc_Alarm1Interrupt
****************************************************************************//**
*
* \brief  This is a weak function and it should be redefined in user source code
*         in condition that such event handler is required.
*
* \param  None
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_Alarm1Interrupt(void);

/*******************************************************************************
* Function Name: Rtc_Alarm2Interrupt
****************************************************************************//**
*
* \brief  This is a weak function and it should be redefined in user source code
*         in condition that such event handler is required.
*
* \param  None
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_Alarm2Interrupt(void);

/*******************************************************************************
* Function Name: Rtc_DstInterrupt
****************************************************************************//**
* 
* \brief  This is a processing handler against the DST event. It adjusts the current 
*         time using the DST start/stop parameters and registers the next DST event time
*         into the ALARM2 interrupt.
* 
* \param  DstTime : The DST configuration structure, see \ref str_rtc_dst_t.
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_DstInterrupt(cy_str_rtc_dst_t const *DstTime);

/*******************************************************************************
* Function Name: Rtc_CenturyInterrupt
****************************************************************************//**
*
* \brief  This is a weak function and it should be redefined in user source code
*         in condition that such event handler is required.
*         By calling this function, it indicates the year reached 2100. It 
*         should add an adjustment to avoid the Y2K problem.
*
* \param  None
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_CenturyInterrupt(void);

/*******************************************************************************
* Function Name: Rtc_GetInterruptStatus
****************************************************************************//**
*
* \brief  Returns a status of RTC interrupt requests.
*
* \param  None
*
* \return Bit mapping information, see \ref group_rtc_macro_interrupts.
*
*******************************************************************************/
uint32_t Cy_Rtc_GetInterruptStatus(void);

/*******************************************************************************
* Function Name: Rtc_GetInterruptStatusMasked
****************************************************************************//**
*
* \brief  Returns an interrupt request register masked by the interrupt mask. Returns a 
*         result of the bitwise AND operation between the corresponding interrupt 
*         request and mask bits.
*
* \param  None
*
* \return Bit mapping information, see \ref group_rtc_macro_interrupts.
*
*******************************************************************************/
uint32_t Cy_Rtc_GetInterruptStatusMasked(void);

/*******************************************************************************
* Function Name: Rtc_GetInterruptMask
****************************************************************************//**
*
* \brief  Returns an interrupt mask.
*
* \param  None
*
* \return Bit mapping information, see \ref group_rtc_macro_interrupts.
*
*******************************************************************************/
uint32_t Cy_Rtc_GetInterruptMask(void);

/*******************************************************************************
* Function Name: Rtc_SetInterrupt
****************************************************************************//**
*
* \brief  Sets a software interrupt request
*
* \param  interruptMask : Bit mask, see \ref group_rtc_macro_interrupts.
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_ClearInterrupt(uint32_t interruptMask);

/*******************************************************************************
* Function Name: Rtc_ClearInterrupt
****************************************************************************//**
*
* \brief  Clears RTC interrupts by setting each bit. 
*
* \param  interruptMask : The bit mask of interrupts to set, see \ref group_rtc_macro_interrupts.
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_SetInterrupt(uint32_t interruptMask);

/*******************************************************************************
* Function Name: Rtc_SetInterruptMask
****************************************************************************//**
*
* \brief  Configures which bits of the interrupt request register will trigger an 
*         interrupt event.
*
* \param  interruptMask : The bit mask of interrupts to set, see \ref group_rtc_macro_interrupts.
*
* \return None
*
*******************************************************************************/
void Cy_Rtc_SetInterruptMask(uint32_t interruptMask);

/*******************************************************************************
* Function Name: Rtc_Interrupt
****************************************************************************//**
*
* \brief  The interrupt handler function which should be called in user provided
*         RTC interrupt function.
*
* This is the handler of the RTC interrupt in CPU NVIC. The handler checks 
* which RTC interrupt was asserted and calls the respective RTC interrupt 
* handler functions: Rtc_Alarm1Interrupt(), Rtc_Alarm2Interrupt() or 
* Rtc_DstInterrupt(), and Rtc_CenturyInterrupt().
* 
* The order of the RTC handler functions execution is incremental. 
* Rtc_Alarm1Interrupt() is run as the first one and Rtc_CenturyInterrupt()
* is called as the last one.
*
* This function clears the RTC interrupt every time when it is called.
*
* Rtc_DstInterrupt() function is called instead of RTC_Alarm2Interrupt() 
* in condition that the mode parameter is true.
*
* \param  DstTime : The daylight saving time configuration structure, see \ref str_rtc_dst_t.
*         mode false : if the DST is disabled, true - if DST is enabled.
*
* \note  This function is required to be called in user interrupt handler.
*
*******************************************************************************/
void Cy_Rtc_Interrupt(cy_str_rtc_dst_t const *DstTime, bool mode);


#endif /* _CY_RTC_H_ */

#if defined(__cplusplus)
}
#endif
/** \} group_rtc_functions */
/** \} group_rtc */


/* [] END OF FILE */
